﻿using System;
using System.Collections.Generic;
using System.Text;
using Xunit;

namespace xUnitTester.ControllerTesting
{

    public class HomeControllerTesting
    {

        public class IndexMethodTesting
        {
            [Fact]
            public void IndexMethod_Get()
            {
                var ctl = new SVN.Net.Controllers.HomeController();
                ctl.ControllerContext = new MvcFakes.FakeControllerContext(ctl, "GET", null, null);

                var result = ctl.Index();

                Assert.IsType<System.Web.Mvc.ViewResult>(result);
                Assert.Equal<int>(ctl.ViewData.Count, 2);
                Assert.Equal<string>("Home Page", (string)ctl.ViewData["Title"]);
                Assert.Equal<string>("Welcome to SVN.Net!", (string)ctl.ViewData["Message"]);
            }

            [Fact]
            public void IndexMethod_Post()
            {
                var ctl = new SVN.Net.Controllers.HomeController();
                ctl.ControllerContext = new MvcFakes.FakeControllerContext(ctl, "POST", null, null);

                var result = ctl.Index();

                Assert.IsType<System.Web.Mvc.ViewResult>(result);
                Assert.Equal<int>(0, ctl.ViewData.Count);
            }
        }

        public class AboutMethodTesting
        {
            [Fact]
            public void AboutMethod()
            {
                var ctl = new SVN.Net.Controllers.HomeController();

                var result = ctl.About();

                Assert.IsType<System.Web.Mvc.ViewResult>(result);
                Assert.Equal<int>(ctl.ViewData.Count, 1);
                Assert.Equal<string>("About Page", (string)ctl.ViewData["Title"]);
            }
        }

        public class ExportMethodTesting
        {
            [Fact]
            public void ExportMethod_WithArgs()
            {
                var moqSVN = new Moq.Mock<SVN.Net.Models.ISVNProvider>();
                string r = string.Empty;
                moqSVN.Expect<byte[]>(svn => svn.Export("", "", "", ref r)).Returns(new byte[] { });
                var ctl = new SVN.Net.Controllers.HomeController(moqSVN.Object);
                var sessions = new System.Web.SessionState.SessionStateItemCollection();
                sessions["uid"] = "username";
                sessions["pwd"] = "password";
                ctl.ControllerContext = new MvcFakes.FakeControllerContext(ctl, sessions);

                var result = ctl.Export("file:///D:/svn.net/repo/trunk");

                Assert.IsType<SVN.Net.Misc.SVNExportResult>(result);
                var exp_result = (SVN.Net.Misc.SVNExportResult)result;
                Assert.Equal<string>("trunk", exp_result.Name);
                Assert.IsType<byte[]>(exp_result.Content);
            }
        }

        public class NavigateMethodTesting
        {

            SVN.Net.Controllers.HomeController _ctl;
            Moq.Mock<SVN.Net.Models.ISVNProvider> _moqSVN;
            SVN.Net.Models.SVN.ProcessXmlResult _xmlResult;

            public NavigateMethodTesting()
            {
                _moqSVN = new Moq.Mock<SVN.Net.Models.ISVNProvider>();
                _xmlResult = new SVN.Net.Models.SVN.ProcessXmlResult(true, Properties.Resources.fakeListResult, "");
                _moqSVN.Expect<SVN.Net.Models.SVN.ProcessXmlResult>(svn => svn.List(Moq.It.IsAny<string>(), Moq.It.IsAny<string>(), Moq.It.IsAny<string>())).Returns(_xmlResult);
                var sessions = new System.Web.SessionState.SessionStateItemCollection();
                sessions["uid"] = "username";
                sessions["pwd"] = "password";
                _ctl = new SVN.Net.Controllers.HomeController(_moqSVN.Object);
                _ctl.ControllerContext = new MvcFakes.FakeControllerContext(_ctl, sessions);
            }

            [Fact]
            public void NavigateMethod_SaveUidAndPwd()
            {
                
                var result = _ctl.Navigate("file:///D:/svn.net/repo/trunk", "usernameA", "passwordA");

                Assert.Equal<string>("usernameA", (string)_ctl.ControllerContext.HttpContext.Session["uid"]);
                Assert.Equal<string>("passwordA", (string)_ctl.ControllerContext.HttpContext.Session["pwd"]);
            }

            [Fact]
            public void NavigateMethod_DoNotSaveUidAndPwd()
            {

                var result = _ctl.Navigate("file:///D:/svn.net/repo/trunk", "", "");

                Assert.Equal<string>("username", (string)_ctl.ControllerContext.HttpContext.Session["uid"]);
                Assert.Equal<string>("password", (string)_ctl.ControllerContext.HttpContext.Session["pwd"]);
            }

            [Fact]
            public void NavigateMethod_ErrorThrought()
            {
                var moqSVN = new Moq.Mock<SVN.Net.Models.ISVNProvider>();
                var xmlResult = new SVN.Net.Models.SVN.ProcessXmlResult(false, Properties.Resources.fakeListResult, "Faking error message.");
                moqSVN.Expect<SVN.Net.Models.SVN.ProcessXmlResult>(svn => svn.List(Moq.It.IsAny<string>(), Moq.It.IsAny<string>(), Moq.It.IsAny<string>())).Returns(xmlResult);
                var sessions = new System.Web.SessionState.SessionStateItemCollection();
                sessions["uid"] = "username";
                sessions["pwd"] = "password";
                var ctl = new SVN.Net.Controllers.HomeController(moqSVN.Object);
                ctl.ControllerContext = new MvcFakes.FakeControllerContext(ctl, sessions);
                
                Assert.Throws<SVN.Net.Models.SVN.SvnException>("Faking error message.", () => ctl.Navigate("file:///D:/svn.net/repo/trunk", "", ""));
            }

            [Fact]
            public void NavigateMethod_ResultVerify()
            {

                var result = _ctl.Navigate("file:///D:/svn.net/repo/trunk", "", "");

                Assert.IsType<System.Web.Mvc.ViewResult>(result);
                Assert.Equal<int>(1, _ctl.ViewData.Count);
                Assert.Equal<string>("file:///D:/svn.net/repo/trunk", (string)_ctl.ViewData["repo"]);
                Assert.IsType<SVN.Net.Models.SVN.ItemCollection>(_ctl.ViewData.Model);
            }
        }

    }

}
